#include <string.h>
#include "gkt_driver.h"
#include "gkt_door.h"
#include "gkt_backboard.h"
#include "window_common.h"

#if defined(GKT_CONFIG_DOOR_LOCK_AUTOMATIC) && GKT_CONFIG_DOOR_LOCK_AUTOMATIC

enum {
	TIMER_ID_DELAY_ACTION = 0,
	TIMER_ID_TIMEOUT,
	TIMER_ID_EXIT,
	TIMER_ID_MAX
};

enum {
	WIDGET_ID_HINT,
	WIDGET_ID_MAX
};

#define WINDOW_KEY_CLOSE_LOCK_STANDBY_TIME_MS 2000

enum {
	WINDOW_ST_INIT = 0,
	WINDOW_ST_TODO_ACTION,
	WINDOW_ST_WAIT_LOCK_RESULT,
	WINDOW_ST_DONE,
	WINDOW_ST_MAX
};

#define WINDOW_LOCK_KEY_DL_TRY_MAXTIMES	3

struct _window_key_dl {
	int	state;
	uint32_t	try_times;
};
static struct _window_key_dl s_window_key_dl;

static void window_key_double_lock_done(uint32_t voice_id)
{
	s_window_key_dl.state = WINDOW_ST_DONE;
	gkt_window_voice_play(NULL, voice_id, GKT_WINDOW_VOICE_F_NOTIFY_END, NULL);

	gkt_window_timer_set(TIMER_ID_EXIT, 2000, 0, 0);
}
static void window_key_double_lock_complete(void)
{
	window_key_double_lock_done(WINDOW_VOICE_COMBINED_ID(lock_already_closed));
}
static void window_key_double_lock_failed(void)
{
	window_key_double_lock_done(WINDOW_VOICE_COMBINED_ID(operation_timeout));
}

static void window_key_double_lock_do(void)
{
	uint32_t timeout;
	int retval;

	gkt_info("window_key_dl_do: state(%u) try_times(%u)\n",
		s_window_key_dl.state, s_window_key_dl.try_times);

	s_window_key_dl.try_times++;
	if (s_window_key_dl.try_times <= WINDOW_LOCK_KEY_DL_TRY_MAXTIMES) {
		retval = gkt_door_lock_close(1);
		if (GKT_SUCCESS == retval)
			window_key_double_lock_complete();
		else if (GKT_EINPROCESS == retval) {
			s_window_key_dl.state = WINDOW_ST_WAIT_LOCK_RESULT;
			timeout = gkt_door_lock_get_timeout(GKT_DOOR_LOCK_OP_DOUBLE_CLOSE) + 1000;
			gkt_window_timer_set(TIMER_ID_TIMEOUT, timeout, 0, 0);
		}
		else {
			gkt_error("window_key_dl_do: lock close request failed %d\n", retval);
			gkt_door_lock_reset();
			window_key_double_lock_do();
		}
	}
	else
		window_key_double_lock_failed();
}

static void window_key_double_lock_todo(void)
{
	int retval;

	s_window_key_dl.try_times = 0;
	retval = gkt_window_timer_set(TIMER_ID_DELAY_ACTION, 100, 0, 0);
	if (GKT_SUCCESS == retval)
		s_window_key_dl.state = WINDOW_ST_TODO_ACTION;
	else
		window_key_double_lock_do();
}

static int window_key_double_lock_event_handler(
				uint32_t major_type, uint32_t minor_type, 
				uint32_t id, uint32_t data)
{
	int retval = GKT_EVENT_HANDLE_CONTINUE;

	gkt_info("window_key_dl: (%u) (%u- %u)(0x%x - 0x%x)\n",
		s_window_key_dl.state, major_type, minor_type, id, data);

	switch(major_type) {
		case GKT_EVENT_WINDOW:
			if (minor_type == GKT_WINDOW_INIT) {
				if (GKT_DOOR_KEY_ONLY_NOTIFY_CLOSED_STATUS == data)
					s_window_key_dl.state = WINDOW_ST_DONE;
				else
					s_window_key_dl.state = WINDOW_ST_INIT;
			}
			else if (minor_type == GKT_WINDOW_ACTIVE) {
				if (WINDOW_ST_DONE == s_window_key_dl.state) {
					window_common_mask_all();
					window_key_double_lock_complete();
					retval = GKT_EVENT_HANDLE_COMPLETE;
				}
				else {
					s_window_key_dl.state = WINDOW_ST_INIT;
					s_window_key_dl.try_times = 0;
#if defined(GKT_CONFIG_NETWORK_ENABLE) && GKT_CONFIG_NETWORK_ENABLE
					gkt_network_set_sync_time_enable(0);
#endif
					gkt_window_switch_control(0);
#if defined(GKT_CONFIG_DOOR_KEY_ENABLE) && GKT_CONFIG_DOOR_KEY_ENABLE
					gkt_door_key_mask((1U << GKT_DOOR_KEY_OPEN) | (1U << GKT_DOOR_KEY_DOUBLE_LOCK));
#endif
					window_common_mask_all();

					window_key_double_lock_todo();
				}
			}
			else if (minor_type == GKT_WINDOW_UNINIT) {
				gkt_driver_set_lp_mode(GKT_DRIVER_LP_FAST_RESTORE);
				gkt_window_system_standby(1);
			}
			break;
		case GKT_EVENT_SYSTEM:
			if ((GKT_WINDOW_SYSTEM_DOOR == minor_type)
				&& (GKT_DOOR_NOTIFY_LOCK_STATUS == id)
				&& (WINDOW_ST_WAIT_LOCK_RESULT == s_window_key_dl.state))
			{
				gkt_window_timer_clear(TIMER_ID_TIMEOUT);
				if (GKT_DOOR_LOCK_ST_DL_CLOSED == data)
					window_key_double_lock_complete();
				else if (GKT_DOOR_LOCK_ST_DL_CLOSE_FAILED == data)
					window_key_double_lock_do();
			}
			break;
		case GKT_EVENT_TIMER:
			if ((TIMER_ID_DELAY_ACTION == minor_type)
				&& (WINDOW_ST_TODO_ACTION == s_window_key_dl.state)) 
			{
				window_key_double_lock_do();
			}
			else if ((TIMER_ID_TIMEOUT == minor_type)
				&& (WINDOW_ST_WAIT_LOCK_RESULT == s_window_key_dl.state))
			{
				window_key_double_lock_do();
			}
			else if (TIMER_ID_EXIT == minor_type)
				gkt_window_exit();
			break;
		default:
			break;
	}

	return retval;
}
GKT_WINDOW_DESC_DEFINE_NO_WIDGETS(key_double_lock);

#endif

